package com.yzy.soft.system.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.TypeReference;
import com.jayway.jsonpath.JsonPath;
import com.jayway.jsonpath.ReadContext;
import com.yzy.soft.common.persistence.dao.UrlJsonFieldsStructureMapper;
import com.yzy.soft.common.persistence.model.UrlJsonFieldsStructure;
import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class JsonUtils {
    @Autowired
    private UrlJsonFieldsStructureMapper urlJsonFieldsStructureMapper;


    private static Logger logger = LoggerFactory.getLogger(JsonUtils.class);
    private static Map<String, List<String>> valueMap = new HashMap<String, List<String>>();
    private static Map<String, Integer> fieldsStructureMap = new HashMap<String, Integer>();
    private static String FIELD_TYPE_ARRAY = "array";
    private static String FIELD_TYPE_MAP = "map";
    private static String FIELD_TYPE_TEXT = "text";
    private int maxLevel = 0;

    public int getMaxLevel() {
        return maxLevel;
    }

    public void setMaxLevel(int maxLevel) {
        this.maxLevel = maxLevel;
    }

    /**
     * 遍历json串，把结果放在valueMap中
     *
     * @param jsonStr
     */
    private void setValueMap(String jsonStr) {
        Map<String, String> jsonMap = new HashMap<String, String>();
        // 数组类型和map类型分开处理
        if (jsonStr.startsWith("[")) {
            JSONArray jsonArray = JSON.parseArray(jsonStr);
            if (CollectionUtils.isNotEmpty(jsonArray)) {
                for (int i = 0; i < jsonArray.size(); i++) {
                    String objStr = jsonArray.get(i).toString();
                    setValueMap(objStr);
                }
            }
        } else if (jsonStr.startsWith("{")) {
            jsonMap = JSON.parseObject(jsonStr,
                    new TypeReference<Map<String, String>>() {
                    });
            for (Map.Entry<String, String> entry : jsonMap.entrySet()) {
                String key = entry.getKey();
                System.out.println("key:" + key);
                String value = entry.getValue();
                List<String> valueList = null;
                // 如果valueMap中已经包含某个key了，就获取valueList，往里面加value
                // 如果不包含就创建一个valueList
                if (valueMap.containsKey(key)) {
                    valueList = valueMap.get(key);
                } else {
                    valueList = new ArrayList<String>();
                }
                valueList.add(value);
                // 数组和map需要进一步递归处理，如果只是单值，直接放到valueMap中即可
                if (value.startsWith("[") || value.startsWith("{")) {
                    setValueMap(value);


                } else {
                    valueMap.put(key, valueList);
                }
            }
        }
    }

    private void getFieldsStructure(String jsonStr, int level, List<UrlJsonFieldsStructure> domain, UrlJsonFieldsStructure ujfs) {
//        if (level > maxLevel) {
//            maxLevel=level;
//            System.out.println("max leave:"+maxLevel);
//        }
        UrlJsonFieldsStructure urlJsonFieldsStructure = null;









        Map<String, String> jsonMap = new HashMap<String, String>();
        // 数组类型和map类型分开处理
        if (jsonStr.startsWith("[")) {
            JSONArray jsonArray = JSON.parseArray(jsonStr);
            if (CollectionUtils.isNotEmpty(jsonArray)) {
                for (int i = 0; i < jsonArray.size(); i++) {
                    String objStr = jsonArray.get(i).toString();
                    getFieldsStructure(objStr, level + 1, domain, ujfs);
                }
            }
        } else if (jsonStr.startsWith("{")) {
            jsonMap = JSON.parseObject(jsonStr,
                    new TypeReference<Map<String, String>>() {
                    });
            for (Map.Entry<String, String> entry : jsonMap.entrySet()) {
                String key = entry.getKey();
                String value = entry.getValue();
                List<String> valueList = null;
                // 如果valueMap中已经包含某个key了，就获取valueList，往里面加value
                // 如果不包含就创建一个valueList
//                valueList.add(value);
                boolean b = fieldsStructureMap.containsKey(key);
                if (b) {
//                    valueList = valueMap.get(key);
                } else {
                    urlJsonFieldsStructure = new UrlJsonFieldsStructure();
                    urlJsonFieldsStructure.setFieldName(key);
                    urlJsonFieldsStructure.setFieldType(JsonUtils.FIELD_TYPE_MAP);
                    urlJsonFieldsStructure.setLevel(level);
                    if (level != 1) {
                        urlJsonFieldsStructure.setParentName(ujfs.getFieldName());
                        urlJsonFieldsStructure.setParentType(ujfs.getFieldType());
                        urlJsonFieldsStructure.setParentLevel(ujfs.getLevel());
                    }

                    if (urlJsonFieldsStructure.getLevel() > maxLevel) {
                        maxLevel=urlJsonFieldsStructure.getLevel();
                        System.out.println("max leave:"+maxLevel);
                    }

                    if (value.startsWith("[")) {
                        urlJsonFieldsStructure.setFieldType(JsonUtils.FIELD_TYPE_ARRAY);
                    } else if (value.startsWith("{")) {
                        urlJsonFieldsStructure.setFieldType(JsonUtils.FIELD_TYPE_MAP);
                    } else {
                        urlJsonFieldsStructure.setFieldType(JsonUtils.FIELD_TYPE_TEXT);
                    }
//                    valueList = new ArrayList<String>();
                    domain.add(urlJsonFieldsStructure);
                    // 数组和map需要进一步递归处理，如果只是单值，直接放到valueMap中即可
                    if (value.startsWith("[") || value.startsWith("{")) {
                        getFieldsStructure(value, level + 1, domain, urlJsonFieldsStructure);
                    } else {
                        fieldsStructureMap.put(key, level);
                    }
                }

            }
        }
    }


    /**
     * 获取报文中某个节点的值
     *
     * @param jsonStr
     * @param name
     * @return
     */
    public List<String> getValueByName(String jsonStr, String name) {
        List<String> valueList = null;
        try {
            valueList = new ArrayList<String>();
            setValueMap(jsonStr);
            valueList = valueMap.get(name);
            return valueList;
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            valueMap.clear();
        }
        return valueList;
    }


    /**
     * 修改报文中，某个节点的值
     *
     * @param jsonStr
     * @param name
     * @param value
     * @return
     */
    public String setValueByName(String jsonStr, String name, String value) {
        List<String> valueList = getValueByName(jsonStr, name);
        if (valueList != null) {
            // 用传进来的值value，替换原始数据
            jsonStr = jsonStr.replace(valueList.get(0), value);
        } else {
            return null;
        }
        return jsonStr;
    }

    public static List<String> getValueByPath(String jsonStr, String jsonPath) {
        ReadContext context = JsonPath.parse(jsonStr);
        List<String> valueList = context.read(jsonPath);
        return valueList;
    }

    public static void main(String[] args) {

//        String ss = "{\"title\":\"新增的任务的表单信息\",\"type\":\"object\",\"properties\":{\"finishTime\":{\"type\":\"number\",\"title\":\"任务结束时间例如：1450708950086\"},\"contactEmail\":{\"type\":\"string\",\"title\":\"联系人邮箱\"},\"sexType\":{\"type\":\"string\",\"title\":\"招聘性别要求,FEMALE:女，MALE：男，UNKWON：男女不限\"},\"enrollEndTime\":{\"type\":\"number\",\"title\":\"报名截止时间例如：1450708950086\"},\"description\":{\"type\":\"string\",\"title\":\"备注\"},\"weekday\":{\"type\":\"string\",\"title\":\"工作日期\"},\"title\":{\"type\":\"string\",\"title\":\"任务标题\"},\"startTime\":{\"type\":\"number\",\"title\":\"任务开始时间,例如：1450708950086\"},\"contactTelephone\":{\"type\":\"string\",\"title\":\"联系人电话\"},\"timeDescription\":{\"type\":\"string\",\"title\":\"工作时间描述\"},\"paymentType\":{\"type\":\"string\",\"title\":\"支付类型 0：线上支付，1：线下支付\"},\"addressList\":{\"items\":{\"properties\":{\"latitude\":{\"type\":\"string\",\"title\":\"纬度\"},\"cityName\":{\"type\":\"string\",\"title\":\"城市名称\"},\"areaName\":{\"type\":\"string\",\"title\":\"区域名称\"},\"longitude\":{\"type\":\"string\",\"title\":\"经度\"},\"address\":{\"type\":\"string\",\"title\":\"t工作地点\"}},\"type\":\"object\",\"description\":\"任务地址\"},\"type\":\"array\",\"title\":\"地址列表\"},\"balanceUnit\":{\"type\":\"string\",\"title\":\"兼职金额单位；例如：元/小时，元/天等\"},\"contactName\":{\"type\":\"string\",\"title\":\"联系人姓名\"},\"content\":{\"type\":\"string\",\"title\":\"工作内容\"},\"balance\":{\"type\":\"number\",\"title\":\"兼职金额\"},\"headcount\":{\"type\":\"integer\",\"title\":\"招聘人数\"},\"typeDesc\":{\"type\":\"string\",\"title\":\"任务类型描述: 只有在任务类型为其他时有效\"},\"type\":{\"type\":\"string\",\"title\":\"任务类型；例如：传单派发，服务员等\"},\"balanceType\":{\"type\":\"integer\",\"title\":\"结算类型；例如：完工结，日结等\"},\"array\":{\"arrayTest\":[\"integer\",\"integer\"]}}}";
//        ss ="{\"title\": \"新增的任务的表单信息\"}";
        String ss ="{\"code\":\"00\",\"count\":10,\"data\":[{\"collation\":\"\",\"comment\":\"\",\"createtime\":\"2018-12-19 20:11:24\",\"databaseId\":14,\"default\":\"\",\"deleteflag\":\"\",\"extra\":\"\",\"field\":\"Id\",\"id\":3464,\"key\":\"\",\"lastupdategoal\":\"\",\"lastupdatetime\":\"2018-12-19 20:11:24\",\"length\":\"10\",\"makegoal\":\"\",\"null\":\"\",\"privileges\":\"\",\"sparefield1\":\"\",\"sparefield2\":\"\",\"sparefield3\":\"\",\"sparefield4\":\"\",\"sparefield5\":\"\",\"sparefield6\":\"\",\"spareflag1\":\"\",\"spareflag2\":\"\",\"spareflag3\":\"\",\"spareflag4\":\"\",\"spareflag5\":\"\",\"tableId\":154,\"type\":\"INT\",\"userflag\":1},{\"collation\":\"\",\"comment\":\"\",\"createtime\":\"2018-12-19 20:11:24\",\"databaseId\":14,\"default\":\"\",\"deleteflag\":\"\",\"extra\":\"\",\"field\":\"Name\",\"id\":3465,\"key\":\"\",\"lastupdategoal\":\"\",\"lastupdatetime\":\"2018-12-19 20:11:24\",\"length\":\"255\",\"makegoal\":\"\",\"null\":\"\",\"privileges\":\"\",\"sparefield1\":\"\",\"sparefield2\":\"\",\"sparefield3\":\"\",\"sparefield4\":\"\",\"sparefield5\":\"\",\"sparefield6\":\"\",\"spareflag1\":\"\",\"spareflag2\":\"\",\"spareflag3\":\"\",\"spareflag4\":\"\",\"spareflag5\":\"\",\"tableId\":154,\"type\":\"VARCHAR\",\"userflag\":1},{\"collation\":\"\",\"comment\":\"\",\"createtime\":\"2018-12-19 20:11:24\",\"databaseId\":14,\"default\":\"\",\"deleteflag\":\"\",\"extra\":\"\",\"field\":\"Description\",\"id\":3466,\"key\":\"\",\"lastupdategoal\":\"\",\"lastupdatetime\":\"2018-12-19 20:11:24\",\"length\":\"255\",\"makegoal\":\"\",\"null\":\"\",\"privileges\":\"\",\"sparefield1\":\"\",\"sparefield2\":\"\",\"sparefield3\":\"\",\"sparefield4\":\"\",\"sparefield5\":\"\",\"sparefield6\":\"\",\"spareflag1\":\"\",\"spareflag2\":\"\",\"spareflag3\":\"\",\"spareflag4\":\"\",\"spareflag5\":\"\",\"tableId\":154,\"type\":\"VARCHAR\",\"userflag\":1},{\"collation\":\"\",\"comment\":\"\",\"createtime\":\"2018-12-19 20:11:24\",\"databaseId\":14,\"default\":\"\",\"deleteflag\":\"\",\"extra\":\"\",\"field\":\"Author\",\"id\":3467,\"key\":\"\",\"lastupdategoal\":\"\",\"lastupdatetime\":\"2018-12-19 20:11:24\",\"length\":\"255\",\"makegoal\":\"\",\"null\":\"\",\"privileges\":\"\",\"sparefield1\":\"\",\"sparefield2\":\"\",\"sparefield3\":\"\",\"sparefield4\":\"\",\"sparefield5\":\"\",\"sparefield6\":\"\",\"spareflag1\":\"\",\"spareflag2\":\"\",\"spareflag3\":\"\",\"spareflag4\":\"\",\"spareflag5\":\"\",\"tableId\":154,\"type\":\"VARCHAR\",\"userflag\":1},{\"collation\":\"\",\"comment\":\"\",\"createtime\":\"2018-12-19 20:11:24\",\"databaseId\":14,\"default\":\"\",\"deleteflag\":\"\",\"extra\":\"\",\"field\":\"Inventiontime\",\"id\":3468,\"key\":\"\",\"lastupdategoal\":\"\",\"lastupdatetime\":\"2018-12-19 20:11:24\",\"length\":\"19\",\"makegoal\":\"\",\"null\":\"\",\"privileges\":\"\",\"sparefield1\":\"\",\"sparefield2\":\"\",\"sparefield3\":\"\",\"sparefield4\":\"\",\"sparefield5\":\"\",\"sparefield6\":\"\",\"spareflag1\":\"\",\"spareflag2\":\"\",\"spareflag3\":\"\",\"spareflag4\":\"\",\"spareflag5\":\"\",\"tableId\":154,\"type\":\"TIMESTAMP\",\"userflag\":1},{\"collation\":\"\",\"comment\":\"\",\"createtime\":\"2018-12-19 20:11:24\",\"databaseId\":14,\"default\":\"\",\"deleteflag\":\"\",\"extra\":\"\",\"field\":\"Url\",\"id\":3469,\"key\":\"\",\"lastupdategoal\":\"\",\"lastupdatetime\":\"2018-12-19 20:11:24\",\"length\":\"255\",\"makegoal\":\"\",\"null\":\"\",\"privileges\":\"\",\"sparefield1\":\"\",\"sparefield2\":\"\",\"sparefield3\":\"\",\"sparefield4\":\"\",\"sparefield5\":\"\",\"sparefield6\":\"\",\"spareflag1\":\"\",\"spareflag2\":\"\",\"spareflag3\":\"\",\"spareflag4\":\"\",\"spareflag5\":\"\",\"tableId\":154,\"type\":\"VARCHAR\",\"userflag\":1},{\"collation\":\"\",\"comment\":\"列名\",\"createtime\":\"2018-12-19 20:11:24\",\"databaseId\":14,\"default\":\"\",\"deleteflag\":\"\",\"extra\":\"\",\"field\":\"ColumnName\",\"id\":3470,\"key\":\"\",\"lastupdategoal\":\"\",\"lastupdatetime\":\"2018-12-19 20:11:24\",\"length\":\"255\",\"makegoal\":\"\",\"null\":\"\",\"privileges\":\"\",\"sparefield1\":\"\",\"sparefield2\":\"\",\"sparefield3\":\"\",\"sparefield4\":\"\",\"sparefield5\":\"\",\"sparefield6\":\"\",\"spareflag1\":\"\",\"spareflag2\":\"\",\"spareflag3\":\"\",\"spareflag4\":\"\",\"spareflag5\":\"\",\"tableId\":154,\"type\":\"VARCHAR\",\"userflag\":1},{\"collation\":\"\",\"comment\":\"对应的java.sql.Types的SQL类型(列类型ID)\",\"createtime\":\"2018-12-19 20:11:24\",\"databaseId\":14,\"default\":\"\",\"deleteflag\":\"\",\"extra\":\"\",\"field\":\"DataType\",\"id\":3471,\"key\":\"\",\"lastupdategoal\":\"\",\"lastupdatetime\":\"2018-12-19 20:11:24\",\"length\":\"10\",\"makegoal\":\"\",\"null\":\"\",\"privileges\":\"\",\"sparefield1\":\"\",\"sparefield2\":\"\",\"sparefield3\":\"\",\"sparefield4\":\"\",\"sparefield5\":\"\",\"sparefield6\":\"\",\"spareflag1\":\"\",\"spareflag2\":\"\",\"spareflag3\":\"\",\"spareflag4\":\"\",\"spareflag5\":\"\",\"tableId\":154,\"type\":\"INT\",\"userflag\":1},{\"collation\":\"\",\"comment\":\"java.sql.Types类型名称(列类型名称)\",\"createtime\":\"2018-12-19 20:11:24\",\"databaseId\":14,\"default\":\"\",\"deleteflag\":\"\",\"extra\":\"\",\"field\":\"DataTypeName\",\"id\":3472,\"key\":\"\",\"lastupdategoal\":\"\",\"lastupdatetime\":\"2018-12-19 20:11:24\",\"length\":\"255\",\"makegoal\":\"\",\"null\":\"\",\"privileges\":\"\",\"sparefield1\":\"\",\"sparefield2\":\"\",\"sparefield3\":\"\",\"sparefield4\":\"\",\"sparefield5\":\"\",\"sparefield6\":\"\",\"spareflag1\":\"\",\"spareflag2\":\"\",\"spareflag3\":\"\",\"spareflag4\":\"\",\"spareflag5\":\"\",\"tableId\":154,\"type\":\"VARCHAR\",\"userflag\":1},{\"collation\":\"\",\"comment\":\"列大小\",\"createtime\":\"2018-12-19 20:11:24\",\"databaseId\":14,\"default\":\"\",\"deleteflag\":\"\",\"extra\":\"\",\"field\":\"ColumnSize\",\"id\":3473,\"key\":\"\",\"lastupdategoal\":\"\",\"lastupdatetime\":\"2018-12-19 20:11:24\",\"length\":\"10\",\"makegoal\":\"\",\"null\":\"\",\"privileges\":\"\",\"sparefield1\":\"\",\"sparefield2\":\"\",\"sparefield3\":\"\",\"sparefield4\":\"\",\"sparefield5\":\"\",\"sparefield6\":\"\",\"spareflag1\":\"\",\"spareflag2\":\"\",\"spareflag3\":\"\",\"spareflag4\":\"\",\"spareflag5\":\"\",\"tableId\":154,\"type\":\"INT\",\"userflag\":1}],\"msg\":\"000\"}";
        JsonUtils json = new JsonUtils();
        List<UrlJsonFieldsStructure> domain = new ArrayList<>();
        UrlJsonFieldsStructure urlJsonFieldsStructure = null;
         json.getFieldsStructure(ss, domain);
        for (int i = 0; i < domain.size(); i++) {
            UrlJsonFieldsStructure urlJsonFieldsStructure1 = domain.get(i);
            System.out.println(urlJsonFieldsStructure1.getFieldName() + " " + urlJsonFieldsStructure1.getFieldType() + " " + urlJsonFieldsStructure1.getLevel());
        }
        System.out.println("max:"+json.getMaxLevel());
//        json.setFieldsStructuralStorage(res);
    }


    public void getFieldsStructure(String ss, List<UrlJsonFieldsStructure> domain) {
//        JsonUtils json = new JsonUtils();
        UrlJsonFieldsStructure urlJsonFieldsStructure = null;
        this.getFieldsStructure(ss, 1, domain, urlJsonFieldsStructure);
//        return domain;
    }
}
